import { _decorator, Asset, Component, Label, Node } from "cc";
const { ccclass, property } = _decorator;

const jsb = (<any>window).jsb;

@ccclass("hotup")
export class hotup extends Component {
  _storagePath: string = "";
  private versionCompareHandle: (versionA: string, versionB: string) => number =
    null!;
  private _am: jsb.AssetsManager = null!;

  @property(Asset)
  manifestUrl: Asset = null!;

  checkCb(event: any) {
    console.log("Code: " + event.getEventCode());
    switch (event.getEventCode()) {
      case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
        console.log(
          "@！！@测试点",
          "No local manifest file found, hot update skipped."
        );
        break;
      case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
      case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
        console.log(
          "@！！@测试点",
          "Fail to download manifest file, hot update skipped."
        );
        break;
      case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
        console.log(
          "@！！@测试点",
          "Already up to date with the latest remote version."
        );
        break;
      case jsb.EventAssetsManager.NEW_VERSION_FOUND:
        console.log(
          "@！！@测试点",
          "New version found, please try to update. (" +
            Math.ceil(this._am.getTotalBytes() / 1024) +
            "kb)"
        );
        break;
      default:
        return;
    }
    console.log(
      "@！！@测试点",
      "Download progress: " +
        event.getPercent() +
        "% (" +
        event.getDownloadedFiles() +
        "/" +
        event.getTotalFiles() +
        ")"
    );
    console.log(
      "@！！@测试点",
      "Download bytes: " +
        event.getDownloadedBytes() +
        "/" +
        event.getTotalBytes()
    );

    this._am.setEventCallback(null!);
  }

  onLoad() {
    // 只有原生平台有效
    if (!jsb) {
      return;
    }

    this._storagePath =
      (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : "/") +
      "blackjack-remote-asset";
    this.node.getComponent(Label).string = this._storagePath;

    this.versionCompareHandle = function (versionA: string, versionB: string) {
      console.log(
        "JS Custom Version Compare: version A is " +
          versionA +
          ", version B is " +
          versionB
      );
      var vA = versionA.split(".");
      var vB = versionB.split(".");
      for (var i = 0; i < vA.length; ++i) {
        var a = parseInt(vA[i]);
        var b = parseInt(vB[i] || "0");
        if (a === b) {
          continue;
        } else {
          return a - b;
        }
      }
      if (vB.length > vA.length) {
        return -1;
      } else {
        return 0;
      }
    };

    // 创建热更新器
    this._am = new jsb.AssetsManager(
      this.manifestUrl.nativeUrl,
      this._storagePath,
      this.versionCompareHandle
    );

    this._am.setVerifyCallback(function (path: string, asset: any) {
      // When asset is compressed, we don't need to check its md5, because zip file have been deleted.
      var compressed = asset.compressed;
      // Retrieve the correct md5 value.
      var expectedMD5 = asset.md5;
      // asset.path is relative path and path is absolute.
      var relativePath = asset.path;
      // The size of asset file, but this value could be absent.
      var size = asset.size;
      if (compressed) {
        // panel.info.string = "Verification passed : " + relativePath;
        return true;
      } else {
        // panel.info.string = "Verification passed : " + relativePath + ' (' + expectedMD5 + ')';
        return true;
      }
    });
  }

  start() {
    console.log("!!!!!!!!!!this._am.getState()", this._am.getState());
    console.log(
      "!!!!!!!!!!this.manifestUrl.nativeUrl",
      this.manifestUrl.nativeUrl
    );

    if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
      var url = this.manifestUrl.nativeUrl;
      this._am.loadLocalManifest(url);
    }

    if (
      !this._am.getLocalManifest() ||
      !this._am.getLocalManifest().isLoaded()
    ) {
      console.log("！！！！！！！！！Failed to load local manifest ...");
      return;
    }

    this._am.setEventCallback(this.checkCb.bind(this));

    this._am.checkUpdate();
  }

  update(deltaTime: number) {}
}
